{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 作业二： \n",
    "为MNIST数据集构建一个分类器，并在测试集上达成超过90%的精度 10分 \n",
    "提示：KNeighborsClassifier对这个任务非常有效，你只需要找到合适的超参数即可，可对weights和n_neighbors这两个超参数进行网格搜索"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\tians\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\sklearn\\feature_extraction\\text.py:17: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working\n",
      "  from collections import Mapping, defaultdict\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.datasets import fetch_mldata\n",
    "from sklearn.metrics import confusion_matrix,precision_score,recall_score\n",
    "from sklearn.model_selection import cross_val_score,GridSearchCV\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "%matplotlib inline\n",
    "mnist = fetch_mldata('MNIST original',data_home = './')\n",
    "X,y = mnist['data'], mnist['target']\n",
    "X_train,X_test,y_train,y_test = X[:60000], X[60000:], y[:60000], y[60000:]\n",
    "shuffle_index = np.random.permutation(60000)\n",
    "X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]\n",
    "y_train_9 = (y_train == 9)\n",
    "y_test_9 = (y_test == 9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def show_img1(X,i):\n",
    "    some_digit = X[i]\n",
    "    some_digit_image = some_digit.reshape(28,28)\n",
    "    plt.imshow(some_digit_image,cmap = plt.cm.binary)\n",
    "    plt.show()\n",
    "\n",
    "def show_img2(X,i):\n",
    "    some_digit = X[i]\n",
    "    some_digit_image = some_digit.reshape(28,28)\n",
    "    plt.imshow(some_digit_image,cmap = plt.cm.binary,interpolation='nearest')\n",
    "    plt.axis('off')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4., 6., 3., 6., 7., 3., 7., 8., 0., 4.])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train[10:20]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAOcAAADnCAYAAADl9EEgAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8GearUAAAG9UlEQVR4nO3dTYjUdRzH8V0RD4aIpgiCJ0VBDwU+BIJKC9ohRMsnWEIEQfTgYSXwiQqC6iLoSSiik3hYsUMQqYhevEiePHjQQHxARRRKUZZa2E7ddr5/mnHdz8y+Xsf98P/PaLz9Qz9mtn9sbKwPyDNtst8AMD5xQihxQihxQihxQqjpDbv/lQsTr3+8H3pyQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQihxQqimXwFIG0ZGRsr98uXLLbevv/66vPb3339v6z3957PPPiv3L7/8suW2ePHi8tpp0/xb/yb524RQ4oRQ4oRQ4oRQ4oRQ4oRQ4oRQ/WNjY9VejlPVy5cvy33Xrl3lfuHChTf5dt6ax48fl/uCBQve0jvpOf3j/dCTE0KJE0KJE0KJE0KJE0KJE0KJE0I55xzHX3/9Ve5Nn4n89ddf237t5cuXl/uRI0fKvenzoH/88cf/fk//+fjjj8t906ZN5X7w4MG2X7vHOeeEbiJOCCVOCCVOCCVOCCVOCOWrMcdx9uzZcu/kqKSvr69v9+7dLbcvvviivPbbb78t906OSpo0/bkvXrxY7qOjo+U+NDT0v99TL/PkhFDihFDihFDihFDihFDihFDihFBT8iNjz58/L/cNGzaU+61btzp6/eoc9e7du+W1x48fL/f58+eX+4EDB8p9yZIlLbd9+/aV1zb96sMZM2aUe3WGe+jQofLaLucjY9BNxAmhxAmhxAmhxAmhxAmhxAmhpuTnOc+dO1funZ5jnjp1qtx37tzZcvv88887eu2TJ0+W++DgYNv3HhgYKPdt27aV+/Xr18v92LFjLbeVK1eW1zadTXcjT04IJU4IJU4IJU4IJU4IJU4IJU4I1bPnnNXnVC9dujShr/3JJ5+U+7Rprf9NXLt2bXnt8PBwuTedB3Zi4cKF5f7VV1+V++bNm8v977//brnt37+/vLbpv+miRYvKPZEnJ4QSJ4QSJ4QSJ4QSJ4QSJ4QSJ4Tq2e+trX5P5dKlSzu6d9NZ4pUrV8p91qxZHb1+t/r555/Lffv27W3fu+napvPhSeZ7a6GbiBNCiRNCiRNCiRNCiRNC9exHxibSsmXLyn2qHpU0+eijj8r9gw8+aLk1fa3mixcvyr36OFpfX/OvJ5wMnpwQSpwQSpwQSpwQSpwQSpwQSpwQyjlnGz799NPJfgtd6Z133in3devWtdyazjmbvhrzwYMH5b548eJynwyenBBKnBBKnBBKnBBKnBBKnBBKnBCqZ885z5w5M2H3TjwT6wWDg4MttxMnTrzFd5LBkxNCiRNCiRNCiRNCiRNCiRNCiRNC9ew556NHjyb7LUBHPDkhlDghlDghlDghlDghlDghlDghVM+ec65atarl9uOPP3Z07xs3bpT7e++919H9oa/PkxNiiRNCiRNCiRNCiRNCiRNC9exRysDAwITd++rVq+W+d+/eCXvtbvbnn3+W+549e9q+94oVK8p97ty5bd97snhyQihxQihxQihxQihxQihxQihxQqiePeecPr31H23mzJnlta9fvy73V69elfvo6Gi5V++tlz18+LDcb9682fa916xZU+5z5sxp+96TxZMTQokTQokTQokTQokTQokTQokTQvWPjY1Vezl2qx07dpT7+fPnO7r/vXv3yn3RokUd3T/V/fv3y33jxo3lfufOnZbbhx9+WF47PDxc7u+++265T7L+8X7oyQmhxAmhxAmhxAmhxAmhxAmhxAmhpuYHCydYr55zXrt2rdybvq+3Osdscvjw4XIPP8dsiycnhBInhBInhBInhBInhBInhJqSHxn75Zdfyn3r1q0d3X/BggXl/ttvv7Xc3n///Y5eu8mjR4/K/Ycffmi5fffdd+W1//zzT7k3fSXp6dOnW25btmwpr509e3a5h/ORMegm4oRQ4oRQ4oRQ4oRQ4oRQ4oRQU/Kcc2RkpNyHhobK/fvvv+/o9efNm9dy++abb8prnz17Vu4//fRTuTf9+sInT56Ue2X16tXlfvTo0XLv9Hy5iznnhG4iTgglTgglTgglTgglTgglTgg1Jc85m9y+fbvc169fX+5Pnz59k28nRtM5ZtPnPQcGBt7k2+klzjmhm4gTQokTQokTQokTQokTQokTQjnnhMnnnBO6iTghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDghlDgh1PSGfdxfTQZMPE9OCCVOCCVOCCVOCCVOCCVOCPUvOMopOWdXmnoAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_img2(X,11)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_img2(X_train,10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(784,)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_digit = X_train[10]\n",
    "test_digit.reshape(1,784)\n",
    "test_digit.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 784)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_digit = X_train[13:14]\n",
    "test_digit.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_digits = X_train[10:20]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 0 ns\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=5, p=2,\n",
       "           weights='uniform')"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%time\n",
    "knn_clf = KNeighborsClassifier()\n",
    "knn_clf.fit(X_train,y_train_9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False, False, False, False, False, False, False,\n",
       "       False])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn_clf.predict(test_digits)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn_clf.predict(test_digit)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 1h 30min 40s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "train_score = cross_val_score(knn_clf,X_train,y_train_9,cv=5,scoring='accuracy')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9913666583071759"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_score.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed: 20.1min remaining:    0.0s\n",
      "[Parallel(n_jobs=1)]: Done   2 out of   2 | elapsed: 39.7min remaining:    0.0s\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 1h 27min 51s\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Done   5 out of   5 | elapsed: 87.9min finished\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "from sklearn.model_selection import cross_val_predict\n",
    "y_train_pred = cross_val_predict(knn_clf,X_train,y_train_9,cv=5,verbose=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 211 ms\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[53761,   290],\n",
       "       [  228,  5721]], dtype=int64)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%time\n",
    "confusion_matrix(y_train_9,y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "精度: 95.18 %\n",
      "召回率: 96.17 %\n"
     ]
    }
   ],
   "source": [
    "print('精度: {0:.2f} %'.format(100*precision_score(y_train_9,y_train_pred)))\n",
    "print('召回率: {0:.2f} %'.format(100*recall_score(y_train_9,y_train_pred)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 17min 11s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "y_test_pred = knn_clf.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[8948,   43],\n",
       "       [  47,  962]], dtype=int64)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "confusion_matrix(y_test_9,y_test_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "精度: 95.72 %\n",
      "召回率: 95.34 %\n"
     ]
    }
   ],
   "source": [
    "print('精度: {0:.2f} %'.format(100*precision_score(y_test_9,y_test_pred)))\n",
    "print('召回率: {0:.2f} %'.format(100*recall_score(y_test_9,y_test_pred)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 5 folds for each of 6 candidates, totalling 30 fits\n",
      "[CV] n_neighbors=2, weights=uniform ..................................\n",
      "[CV]  n_neighbors=2, weights=uniform, score=0.9908340971585701, total=18.9min\n",
      "[CV] n_neighbors=2, weights=uniform ..................................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Done   1 out of   1 | elapsed: 83.3min remaining:    0.0s\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV]  n_neighbors=2, weights=uniform, score=0.9906666666666667, total=16.9min\n",
      "[CV] n_neighbors=2, weights=uniform ..................................\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Done   2 out of   2 | elapsed: 162.4min remaining:    0.0s\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[CV] .... n_neighbors=2, weights=uniform, score=0.99175, total=16.2min\n",
      "[CV] n_neighbors=2, weights=uniform ..................................\n",
      "[CV]  n_neighbors=2, weights=uniform, score=0.9905833333333334, total=15.9min\n",
      "[CV] n_neighbors=2, weights=uniform ..................................\n",
      "[CV]  n_neighbors=2, weights=uniform, score=0.9901658471539295, total=17.2min\n",
      "[CV] n_neighbors=2, weights=distance .................................\n",
      "[CV]  n_neighbors=2, weights=distance, score=0.9917506874427131, total=16.0min\n",
      "[CV] n_neighbors=2, weights=distance .................................\n",
      "[CV] ..... n_neighbors=2, weights=distance, score=0.993, total=16.1min\n",
      "[CV] n_neighbors=2, weights=distance .................................\n",
      "[CV]  n_neighbors=2, weights=distance, score=0.9908333333333333, total=16.2min\n",
      "[CV] n_neighbors=2, weights=distance .................................\n",
      "[CV]  n_neighbors=2, weights=distance, score=0.9918333333333333, total=16.2min\n",
      "[CV] n_neighbors=2, weights=distance .................................\n",
      "[CV]  n_neighbors=2, weights=distance, score=0.9903325277106425, total=16.1min\n",
      "[CV] n_neighbors=4, weights=uniform ..................................\n",
      "[CV]  n_neighbors=4, weights=uniform, score=0.9910840763269727, total=16.3min\n",
      "[CV] n_neighbors=4, weights=uniform ..................................\n",
      "[CV] .... n_neighbors=4, weights=uniform, score=0.99225, total=16.3min\n",
      "[CV] n_neighbors=4, weights=uniform ..................................\n",
      "[CV]  n_neighbors=4, weights=uniform, score=0.9924166666666666, total=16.4min\n",
      "[CV] n_neighbors=4, weights=uniform ..................................\n",
      "[CV]  n_neighbors=4, weights=uniform, score=0.9916666666666667, total=16.5min\n",
      "[CV] n_neighbors=4, weights=uniform ..................................\n",
      "[CV]  n_neighbors=4, weights=uniform, score=0.9907492291024252, total=16.8min\n",
      "[CV] n_neighbors=4, weights=distance .................................\n",
      "[CV]  n_neighbors=4, weights=distance, score=0.9921673193900509, total=16.6min\n",
      "[CV] n_neighbors=4, weights=distance .................................\n",
      "[CV] ..... n_neighbors=4, weights=distance, score=0.993, total=16.5min\n",
      "[CV] n_neighbors=4, weights=distance .................................\n",
      "[CV] .... n_neighbors=4, weights=distance, score=0.9925, total=16.4min\n",
      "[CV] n_neighbors=4, weights=distance .................................\n",
      "[CV]  n_neighbors=4, weights=distance, score=0.9923333333333333, total=16.5min\n",
      "[CV] n_neighbors=4, weights=distance .................................\n",
      "[CV]  n_neighbors=4, weights=distance, score=0.9911659304942079, total=17.7min\n",
      "[CV] n_neighbors=6, weights=uniform ..................................\n",
      "[CV]  n_neighbors=6, weights=uniform, score=0.9905007916006999, total=16.7min\n",
      "[CV] n_neighbors=6, weights=uniform ..................................\n",
      "[CV]  n_neighbors=6, weights=uniform, score=0.9930833333333333, total=16.5min\n",
      "[CV] n_neighbors=6, weights=uniform ..................................\n",
      "[CV]  n_neighbors=6, weights=uniform, score=0.9920833333333333, total=16.4min\n",
      "[CV] n_neighbors=6, weights=uniform ..................................\n",
      "[CV]  n_neighbors=6, weights=uniform, score=0.9909166666666667, total=16.2min\n",
      "[CV] n_neighbors=6, weights=uniform ..................................\n",
      "[CV]  n_neighbors=6, weights=uniform, score=0.9906658888240687, total=16.4min\n",
      "[CV] n_neighbors=6, weights=distance .................................\n",
      "[CV]  n_neighbors=6, weights=distance, score=0.991417381884843, total=16.6min\n",
      "[CV] n_neighbors=6, weights=distance .................................\n",
      "[CV]  n_neighbors=6, weights=distance, score=0.9930833333333333, total=16.6min\n",
      "[CV] n_neighbors=6, weights=distance .................................\n",
      "[CV] ... n_neighbors=6, weights=distance, score=0.99175, total=16.5min\n",
      "[CV] n_neighbors=6, weights=distance .................................\n",
      "[CV]  n_neighbors=6, weights=distance, score=0.9920833333333333, total=16.6min\n",
      "[CV] n_neighbors=6, weights=distance .................................\n",
      "[CV]  n_neighbors=6, weights=distance, score=0.9905825485457121, total=16.4min\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Done  30 out of  30 | elapsed: 2405.3min finished\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 1d 16h 6min 5s\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=5, error_score='raise',\n",
       "       estimator=KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=5, p=2,\n",
       "           weights='uniform'),\n",
       "       fit_params=None, iid=True, n_jobs=1,\n",
       "       param_grid=[{'weights': ['uniform', 'distance'], 'n_neighbors': [2, 4, 6]}],\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',\n",
       "       scoring=None, verbose=3)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%%time\n",
    "param_grid = [{'weights':['uniform','distance'], 'n_neighbors': [2,4,6]}]\n",
    "knn_clf = KNeighborsClassifier() \n",
    "grid_search = GridSearchCV(knn_clf,param_grid,cv=5,verbose=3)\n",
    "grid_search.fit(X_train,y_train_9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'n_neighbors': 4, 'weights': 'distance'}"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grid_search.best_params_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=4, p=2,\n",
       "           weights='distance')"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grid_search.best_estimator_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9922333333333333"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grid_search.best_score_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grid_search.predict(test_digit)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 15min 38s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "y_test_pred = grid_search.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[8954,   37],\n",
       "       [  43,  966]], dtype=int64)"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "confusion_matrix(y_test_9,y_test_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "精度: 96.31 %\n",
      "召回率: 95.74 %\n"
     ]
    }
   ],
   "source": [
    "print('精度: {0:.2f} %'.format(100*precision_score(y_test_9,y_test_pred)))\n",
    "print('召回率: {0:.2f} %'.format(100*recall_score(y_test_9,y_test_pred)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 这里主要是使用了KNN算法实现更精准的分类器，使用gridsearchcv网格搜索，查找出最佳超参数，评估这分类器的准确率和召回率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
